import { Injectable } from "@angular/core";
import { File } from "@ionic-native/file";
import { FileTransfer } from "@ionic-native/file-transfer";
import { LocalStorageService } from "../local-storage/local-storage.service";
import { Platform } from "ionic-angular";
import { normalizeURL } from 'ionic-angular';

export interface FileEntry {
    fullPath: string;
    name: string;
    nativeURL: string;
    isFile: boolean;
    isDirectory: boolean;
}

@Injectable()
export class CacheImgService {
    constructor(private file: File,
                private fileTransfer: FileTransfer,
                private storage: LocalStorageService,
                private platform: Platform) {
    }

    getDir() {
        if(this.platform.is('ios')) {
            return this.file.dataDirectory;
        } else if (this.platform.is('android')) {
            return this.file.externalRootDirectory;
        }
    }

    async checkDir() {
        let dir = this.getDir();
        return await this.file.checkDir(dir, 'cache')
            .then((res) => {
                // console.log(res);
                return res;
            }).catch((err) => {
                console.error(err);
            });
    }

    async createDir() {
        let dir = this.getDir();
        return await this.file.createDir(dir, 'cache', false)
            .then((res) => {
                // console.log(res);
                return res;
            }).catch((err) => {
                console.error(err);
            });
    }

    downLoadImg(source: string, name: string) {
        let dir = this.getDir();
        // console.log('download', dir);
        return this.fileTransfer.create().download(source, dir + 'cache/' + name)
            .then((res: FileEntry) => {
                console.log('download complete', res);
                return res;
            })
            .catch(err => {
                console.error('download error', err);
            });
    }

    getFilePath(key) {
        return new Promise((resolve, reject) => {
            this.storage.getData(key).subscribe((res) => {
                resolve(res);
            }, err => {
                console.error('get file path error', err);
                reject(err);
            });
        });
    }

    setStorage(key, value) {
        return new Promise((resolve, reject) => {
            this.storage.setData(key, value).subscribe((res) => {
                resolve(res);
            }, err => {
                console.error('setStorage error', err);
                reject(err);
            });
        });
    }

    async getImgUrl(fileName: string, azureInfo) {
        let dir = this.getDir();
        let url = await this.getFilePath(fileName) as string;
        if (url) {
            let o = await this.file.checkFile(dir + 'cache/', url);
            if (o) {
                return dir + 'cache/' + url;
            }
            return await this.downloadAndCache(fileName, azureInfo);
        } else {
            return await this.downloadAndCache(fileName, azureInfo);
        }
    }

    async downloadAndCache(fileName, azureInfo) {
        let path = CacheImgService.getCompletePath(fileName, azureInfo);
        if (!await this.checkDir()) {
            await this.createDir();
        }
        let entry = await this.downLoadImg(path, fileName);
        if (entry) {
            await this.setStorage(fileName, fileName);
        }
        //缓存时还是返回原始路径，感觉native下载和UI加载时不同的进程（待验证）
        return path;
        // return this.file.cacheDirectory + 'cache/' + fileName;
    }

    async getImgPath(fileName: string, azureInfo) {
        if (!this.platform.is('cordova')) {
            return CacheImgService.getCompletePath(fileName, azureInfo);
        } else {
            let url = await this.getImgUrl(fileName, azureInfo);
            if (this.platform.is('android')) {
                return url ? url : CacheImgService.getCompletePath(fileName, azureInfo);
            } else if (this.platform.is('ios')) {
                if (url) {
                    if (url.indexOf('http') !== -1) {
                        return url;
                    } else {
                        return normalizeURL(url);
                    }
                } else {
                    return CacheImgService.getCompletePath(fileName, azureInfo);
                }
            } else {
                return CacheImgService.getCompletePath(fileName, azureInfo);
            }
        }
    }

    async clearCache () {
        let dir = this.getDir();
        let o = await this.file.removeRecursively(dir, 'cache');
        console.log(o);
        return await this.storage.clear();
    }

    private static getCompletePath(fileName: string, azureInfo: string): string {
        let azure = JSON.parse(azureInfo);
        return azure['container'] + "/" + fileName + "?" + azure['sas'];
    }

}
